#include "InterfazVotante.h"

InterfazVotante::InterfazVotante() {
	this->votante = NULL;
	this->log = Log::getInstancia();
	this->manejadorVotante = new ManejadorVotante();

}

void InterfazVotante::menuPrincipal() {

	if (this->menuPantallaLogin())
		this->menuVotante();

}

void InterfazVotante::menuVotante() {

	system("clear");

	//chequeo si el votante voto en alguna eleccion con la fecha del dia y en su distrito.
	bool haVotado = false;
	for (unsigned int i = 0; i < votante->getElecciones()->size(); i++) {
		if (Utils::convertirEnteroAString(votante->getElecciones()->at(i)->getFecha()) == Utils::fechaDelDia()) {
			haVotado = true;
			this->log->escribir("el votante ya efectuo su voto.");
			break;
		}
	}

	if (!haVotado) {

		//El votante navegara por todas las elecciones que tenga habilitadas
		ManejadorEleccion* manejadorEleccion = new ManejadorEleccion();
		vector<Eleccion*>* eleccionesDisponibles = manejadorEleccion->recuperarEleccionesFechaYDistrito(Utils::fechaDelDia(), votante->getDistrito()->getNombre());

		//Valido si el votante tiene cargada las elecciones con fecha del dia y para su distrito.
		if (eleccionesDisponibles->size() > 0) {
			for (unsigned int i = 0; i < eleccionesDisponibles->size(); i++) {
				this->menuEleccion(eleccionesDisponibles->at(i));
			}
		} else {
			system("clear");
			cout << "El votante ingresado no se encuentra habilitado para votar en la/s eleccion/es de la fecha del dia." << endl;
			this->log->escribir("El votante ingresado no se encuentra habilitado para votar en la/s eleccion/es de la fecha del dia.");
			getchar();
			cin.ignore();
		}

		//elimino los elecciones
		for (unsigned int i = 0; i < eleccionesDisponibles->size(); i++) {
			delete eleccionesDisponibles->at(i);
		}
		delete eleccionesDisponibles;
		delete manejadorEleccion;
	} else {
		system("clear");
		cout << "El votante ingresado ha realizado la votacion correspondiente a la fecha del dia." << endl;
		this->log->escribir("El votante ingresado ha realizado la votacion correspondiente a la fecha del dia.");
		getchar();
		cin.ignore();
	}
}

bool InterfazVotante::menuEleccion(Eleccion* eleccion) {

	system("clear");
	bool haConfirmado = false;

	while (!haConfirmado) {
		system("clear");
		//recorro las lista y las muestro por pantalla como opciones a elegir.
		ManejadorLista* manejadorLista = new ManejadorLista();
		vector<Lista*>* listasDeEleccion = manejadorLista->recuperarListasPorFechaYCargo(eleccion->getFecha(), eleccion->getCargo()->getNombre());

		//valido si hay listas asociadas a la eleccion
		if (listasDeEleccion->size() > 0) {

			cout << "Eleccion de " << eleccion->getCargo()->getNombre() << endl;

			if (eleccion->getCargo()->getCargosAsociados()->size() > 0) {

				cout << "Demas cargos a votar: " << endl << endl;
				for (unsigned int i = 0; i < eleccion->getCargo()->getCargosAsociados()->size(); i++) {
					cout << eleccion->getCargo()->getCargosAsociados()->at(i) << " - " << endl;
					if (i % 2 == 0)
						cout << endl;
				}
			}
			cout << endl;
			cout << endl;
			cout << "Eliga uno de los siguientes candidatos: " << endl;

			for (unsigned int i = 0; i < listasDeEleccion->size(); i++) {
				//nombre de lista
				cout << i + 1 << "- " << listasDeEleccion->at(i)->getNombre() << endl;
				cout << "\t";
				ManejadorCandidato* manejadorCandidato = new ManejadorCandidato();
				vector<Candidato*>* candidatosLista = manejadorCandidato->recuperarCandidatosPorLista(Utils::fechaDelDia(), eleccion->getCargo()->getNombre(), listasDeEleccion->at(i)->getNombre());

				//imprimo nombres de todos los candidatos para todos los cargos de esa lista.
				for (unsigned int i = 0; i < candidatosLista->size(); i++) {
					string dni = Utils::convertirEnteroAString(candidatosLista->at(i)->getVotante()->getDNI());
					Votante* candidato = this->manejadorVotante->recuperar(dni);
					if (candidato != NULL)
						cout << candidato->getNombreYApellido() << " - " << endl;
					if (i % 2 == 0)
						cout << endl;
				}
				cout << endl;
				// Elimino los candidatos
				for (unsigned int i = 0; i < candidatosLista->size(); i++) {
					delete candidatosLista->at(i);
				}
				delete manejadorCandidato;
			}

			unsigned int numeroDeLista;

			cout << "Numero de lista a elegir: ";
			cin >> numeroDeLista;

			if (numeroDeLista > 0 && numeroDeLista <= listasDeEleccion->size()) {

				char opcionConfirmacion;

				//confirmacion de la lista elegida
				cout << "¿Ud. desea confirmar la opcion elegida?(S/N): ";
				cin >> opcionConfirmacion;

				switch (opcionConfirmacion) {
				case ('s'):
				case ('S'): {
					//registro un voto en conteo.
					ManejadorConteo* manejadorConteo = new ManejadorConteo();
					string fecha = Utils::fechaDelDia();
					string cargo = eleccion->getCargo()->getNombre();
					string distrito = this->votante->getDistrito()->getNombre();
					string nombreLista = listasDeEleccion->at(numeroDeLista - 1)->getNombre();
					manejadorConteo->registrarVoto(fecha, cargo, distrito, nombreLista);
					Eleccion* eleccionVotante = new Eleccion(*eleccion);
					this->log->escribir("El votante ha efectuado su voto");

					//Registro la eleccion en el votante.
					this->votante->addEleccion(eleccionVotante);
					ManejadorVotante* manejadorVotante = new ManejadorVotante();
					if (manejadorVotante->modificacion(this->votante)) {
						cout << "Su votacion se ha registrado con exito.";
						this->log->escribir("Su votacion se ha registrado con exito.");
					} else {
						cout << "Su votacion no pudo ser egistrada.";
						this->log->escribir("Su votacion no pudo ser egistrada.");
					}

					// Elimino las listas
					for (unsigned int i = 0; i < listasDeEleccion->size(); i++) {
						delete listasDeEleccion->at(i);
					}
					delete listasDeEleccion;
					delete manejadorVotante;
					getchar();
					cin.ignore();
					haConfirmado = true;
					delete manejadorConteo;
					break;
				}
				case ('n'):
				case ('N'):
					break;
				default:
					cout << "opcion incorrecta. Vuelva a intentarlo";
					getchar();
					cin.ignore();
					break;
				}

			} else {
				cout << "opcion incorrecta. Vuelva a intentarlo";
				getchar();
				cin.ignore();
			}
		}else{
			cout<< "La eleccion no tiene listas cargadas";
			this->log->escribir("no existen listas para la eleccion");
			getchar();
			cin.ignore();
			break;
		}

		delete manejadorLista;
	}
	return 0;
}

bool InterfazVotante::validarUsuarioYContrasenia(string usuario, string contrasenia) {
	bool validar = false;
	usuario = Utils::aMinuscula(usuario);
	contrasenia = Utils::aMinuscula(contrasenia);

	ManejadorVotante* manejadorVotante = new ManejadorVotante();
	Votante* votante = manejadorVotante->recuperar(usuario);

	if (votante != NULL) {
		validar = votante->validarContrasenia(contrasenia);
		this->votante = votante;
	}
	delete manejadorVotante;
	return validar;
}

bool InterfazVotante::menuPantallaLogin() {
	system("clear");
	cin.ignore();
	cout << "Menu Login Votante: " << endl;
	cout << endl;
	string usuario = "";
	string contrasenia = "";
	cout << "Usuario: ";
	getline(cin, usuario);
	cout << " " << endl;
	cout << "contraseña: ";
	getline(cin, contrasenia);
	cout << " " << endl;
	if (!this->validarUsuarioYContrasenia(usuario, contrasenia)) {
		cout << endl;
		cout << "Usuario/clave u opcion Incorrecta! Presione una tecla para continuar" << endl;
		this->log->escribir("Usuario/clave u opcion Incorrecta");
		getchar();
		cin.ignore();
		return false;
	} else {
		this->log->escribir("Usuario registrado correctamente");
		return true;
	}

}

InterfazVotante::~InterfazVotante() {
	if (this->votante != NULL)
		delete this->votante;
	delete this->manejadorVotante;
}
